﻿#include "CameraTUCAM_private.h"
#include "./sdk/inc/TUCamApi.h"
#include "CameraTUCAMImageProcessing.h"

namespace Qly {

inline double scaleFromStandardRange(double min, double max, double value)
{
    return min + (value + 1) * (max - min) / 2.0;
}

inline double scaleToStandardRange(double min, double max, double value)
{
    return -1.0 + 2.0 *  (value - min) / (max - min);
}

bool CameraTUCAMImageProcessing::whiteBalanceMode(WhiteBalanceMode &mode)
{
    mode = WhiteBalanceManual;
    return true;
}

bool CameraTUCAMImageProcessing::setManualWhiteBalance(double colorTemperature, double Tint)
{
    return false;
}

bool CameraTUCAMImageProcessing::manualWhiteBalance(double &colorTemperature, double &Tint)
{
    return false;
}

bool CameraTUCAMImageProcessing::setWhiteBalance(int red, int green, int blue)
{
    return false;
}

bool CameraTUCAMImageProcessing::whiteBalance(int &red, int &green, int &blue)
{
    return false;
}

bool CameraTUCAMImageProcessing::setWhiteBalanceMode(WhiteBalanceMode mode)
{
    int nRet = -1;
    switch (mode) {
    case WhiteBalanceManual:
        nRet = TUCAM_Capa_SetValue(m_opCam.hIdxTUCam, (int)TUIDC_ATWBALANCE, 0);
        break;
    case WhiteBalanceAutoOnePush:
        break;
    case WhiteBalanceAutoContinuous:
        nRet = TUCAM_Capa_SetValue(m_opCam.hIdxTUCam, (int)TUIDC_ATWBALANCE, 1);
        break;
    }
    return nRet >= 0;
}


bool CameraTUCAMImageProcessing::whiteBalanceTempRange(int &nMin, int &nMax, int &nValue)
{
    return false;
}

bool CameraTUCAMImageProcessing::whiteBalanceTintRange(int &nMin, int &nMax, int &nValue)
{
    return false;
}

bool CameraTUCAMImageProcessing::setWhiteBalanceTempTint(int temp, int tint)
{
    return false;
}

bool CameraTUCAMImageProcessing::whiteBalanceTempTint(int &temp, int &tint)
{

    return false;
}


bool CameraTUCAMImageProcessing::setGain(double fValue)
{
    if(TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_GLOBALGAIN, fValue, 0) == TUCAMRET_SUCCESS)
    {
        qDebug() << "TUIDP_GLOBALGAIN set to " << fValue;
        return true;
    }
    return false;
}

bool CameraTUCAMImageProcessing::gainMode(GainMode &mode)
{
//Toupcam_get_AutoExpoEnable
    return false;
}

bool CameraTUCAMImageProcessing::setGainMode(GainMode mode)
{
    switch (mode) {
    case GainManual:
        break;
    case GainAutoOnePush:
        break;
    case GainAutoContinuous:
        break;
    }
    return false;
}

bool CameraTUCAMImageProcessing::brightnessEnable(bool &on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = TUIDP_BRIGHTNESS;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        on = true;
    }
    else
    {
        on = false;
    }
    return true;
}

bool CameraTUCAMImageProcessing::setBrightnessEnable(bool on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_BRIGHTNESS;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        if(!on) TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_BRIGHTNESS, prop.dbValDft);
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::setBrightness(double value)
{
    double fvalue = scaleFromStandardRange(m_brightness_min, m_brightness_max, value);
    if(TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_BRIGHTNESS, fvalue, 0) == TUCAMRET_SUCCESS)
    {
        qDebug() << "TUIDP_BRIGHTNESS set to " << fvalue;
        return true;
    }
    return false;
}

bool CameraTUCAMImageProcessing::brightness(double &value)
{
    double fmin, fmax, fValue;
    if(brightnessRange(fmin, fmax, fValue))
    {
        value = scaleToStandardRange(fmin, fmax, fValue);
        return true;
    }
    return false;
}

bool CameraTUCAMImageProcessing::brightnessRange(double &fMin, double &fMax, double &fValue)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_BRIGHTNESS;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        TUCAM_Prop_GetValue(m_opCam.hIdxTUCam, TUIDP_BRIGHTNESS, &fValue, 0);
        fMin = prop.dbValMin;
        fMax = prop.dbValMax;
        fValue = fValue;
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::hue(double &value)
{
    double min, max, nValue;
    if(hueRange(min, max, nValue))
    {
        value = scaleToStandardRange(min, max, nValue);
        return true;
    }
    return false;
}


bool CameraTUCAMImageProcessing::setHue(double value)
{
    double fvalue = scaleFromStandardRange(m_hue_min, m_hue_max, value);
    if(TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_HUE, fvalue, 0) == TUCAMRET_SUCCESS)
    {
        qDebug() << "TUIDP_HUE set to " << fvalue;
    }
    return true;
}

bool CameraTUCAMImageProcessing::hueEnable(bool &on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = TUIDP_HUE;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        on = true;
    }
    else
    {
        on = false;
    }
    return true;
}

bool CameraTUCAMImageProcessing::setHueEnable(bool on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_HUE;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        if(!on) TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_HUE, prop.dbValDft);
        return true;
    }
    else
    {
        return false;
    }
}


bool CameraTUCAMImageProcessing::saturationEnable(bool &on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_SATURATION;
    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        on = true;
    }
    else
    {
        on = false;
    }
    return true;
}

bool CameraTUCAMImageProcessing::setSaturationEnable(bool on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_SATURATION;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        if(!on) TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_SATURATION, prop.dbValDft);
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::contrastEnable(bool &on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_CONTRAST;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        on = true;
    }
    else
    {
        on = false;
    }
    return true;
}

bool CameraTUCAMImageProcessing::setContrastEnable(bool on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_CONTRAST;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        if(!on) TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_CONTRAST, prop.dbValDft);
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::gammaEnable(bool &on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_GAMMA;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        on = true;
    }
    else
    {
        on = false;
    }
    return true;
}

bool CameraTUCAMImageProcessing::setGammaEnable(bool on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_GAMMA;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        if(!on) TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_GAMMA, prop.dbValDft);
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::gammaRange(double &min, double &max, double &fValue)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_GAMMA;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        TUCAM_Prop_GetValue(m_opCam.hIdxTUCam, TUIDP_GAMMA, &fValue, 0);
        min = prop.dbValMin;
        max = prop.dbValMax;
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::hueRange(double &fMin, double &fMax, double &fValue)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_HUE;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        TUCAM_Prop_GetValue(m_opCam.hIdxTUCam, TUIDP_HUE, &fValue, 0);
        fMin = prop.dbValMin;
        fMax = prop.dbValMax;
        fValue = fValue;
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::gain(double &fValue)
{
    double min, max;
    return gainRange(min, max, fValue);
}

bool CameraTUCAMImageProcessing::gainRange(double &fMin, double &fMax, double &fValue)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_GLOBALGAIN;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        TUCAM_Prop_GetValue(m_opCam.hIdxTUCam, TUIDP_GLOBALGAIN, &fValue, 0);
        fMin = prop.dbValMin;
        fMax = prop.dbValMax;
        return true;
    }
    else
    {
        qDebug() << "TUCAM_Prop_GetValue(m_opCam.hIdxTUCam, TUIDP_GLOBALGAIN, &fValue, 0) failed";
        return false;
    }
}

bool CameraTUCAMImageProcessing::contrastRange(double &fMin, double &fMax, double &fValue)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_CONTRAST;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        TUCAM_Prop_GetValue(m_opCam.hIdxTUCam, TUIDP_CONTRAST, &fValue, 0);
        fMin = prop.dbValMin;
        fMax = prop.dbValMax;
        fValue = fValue;

        qDebug() << "CONTRAST min = " << prop.dbValMin << ", max = " << prop.dbValMax << ", default value" << prop.dbValDft;
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::contrast(double &value)
{
    double min, max, nValue;
    if(contrastRange(min, max, nValue))
    {
        value = scaleToStandardRange(min, max, nValue);
        return true;
    }
    return false;
}

bool CameraTUCAMImageProcessing::setContrast(double value)
{
    double fvalue = scaleFromStandardRange(m_contrast_min, m_contrast_max, value);
    if(TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_CONTRAST, fvalue, 0) == TUCAMRET_SUCCESS)
    {
        qDebug() << "TUIDP_CONTRAST = " << fvalue;
    }
    return true;
}

bool CameraTUCAMImageProcessing::saturation(double &value)
{
    double min, max, nValue;
    if(saturationRange(min, max, nValue))
    {
        value = scaleToStandardRange(min, max, nValue);
        return true;
    }
    return false;
}
bool CameraTUCAMImageProcessing::blackLevelRange(double &fMin, double &fMax, double &fValue)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_BLACKLEVEL;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        qDebug() << "TUIDP_BLACKLEVEL min = " << prop.dbValMin << " , max = " << prop.dbValMax << " , Default = " << prop.dbValDft;
        TUCAM_Prop_GetValue(m_opCam.hIdxTUCam, TUIDP_BLACKLEVEL, &fValue, 0);
        fMin = prop.dbValMin;
        fMax = prop.dbValMax;
        fValue = fValue;
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::saturationRange(double &fMin, double &fMax, double &fValue)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_SATURATION;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        double fValue;
        qDebug() << "SATURATION min = " << prop.dbValMin << " , max = " << prop.dbValMax << " , Default = " << prop.dbValDft;
        TUCAM_Prop_GetValue(m_opCam.hIdxTUCam, TUIDP_SATURATION, &fValue, 0);
        fMin = prop.dbValMin;
        fMax = prop.dbValMax;
        fValue = fValue;
        return true;
    }
    else
    {
        return false;
    }
}

bool CameraTUCAMImageProcessing::setSaturation(double value)
{

    double fvalue = scaleFromStandardRange(m_saturation_min, m_saturation_max, value);
    if(TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_SATURATION, fvalue, 0) == TUCAMRET_SUCCESS)
    {
        qDebug() << "TUIDP_SATURATION set to " << fvalue;
    };
    return true;
}

bool CameraTUCAMImageProcessing::gamma(double &v)
{
    double min, max;
//	Toupcam_get_Gamma();
    return gammaRange(min, max, v);
}

bool CameraTUCAMImageProcessing::setGamma(double v)
{
    if(TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_GAMMA, v, 0) == TUCAMRET_SUCCESS)
    {
        qDebug() << "TUIDP_SATURATION set to " << v;
    };
    return true;
}

bool CameraTUCAMImageProcessing::blackLevel(double &value)
{
    double min, max, nValue;
    if(blackLevelRange(min, max, nValue))
    {
        value = scaleToStandardRange(min, max, nValue);
        return true;
    }
    return false;
}

bool Qly::CameraTUCAMImageProcessing::blackLevelEnable(bool &on)
{
    TUCAM_PROP_ATTR prop;
    prop.idProp = 0;
    prop.nIdxChn = 0;
    prop.dbValDft = 0;
    prop.dbValMin = 0;
    prop.dbValMax = 0;
    prop.dbValStep = 0;

    prop.idProp = TUIDP_BLACKLEVEL;

    if (TUCAMRET_SUCCESS == TUCAM_Prop_GetAttr(m_opCam.hIdxTUCam, &prop))
    {
        on = true;
    }
    else
    {
        on = false;
    }
    return true;
}

bool CameraTUCAMImageProcessing::setBlackLevel(double value)
{
    double fvalue = scaleFromStandardRange(m_blackLevel_min, m_blackLevel_max, value);
    if(TUCAM_Prop_SetValue(m_opCam.hIdxTUCam, TUIDP_BLACKLEVEL, fvalue, 0) == TUCAMRET_SUCCESS)
    {
        qDebug() << "TUIDP_BLACKLEVEL set to " << fvalue;
    };
    return true;
}

bool Qly::CameraTUCAMImageProcessing::init(TUCAM_OPEN op)
{
    m_opCam = op;
    double value;
    contrastRange(m_contrast_min, m_contrast_max, value);
    brightnessRange(m_brightness_min, m_brightness_max, value);
    //gainRange(m_gain_min, m_gain_max, value);
    hueRange(m_hue_min, m_hue_max, value);
    saturationRange(m_saturation_min, m_saturation_max, value);
    //gammaRange(m_gamma_min, m_gamma_max, value);
    blackLevelRange(m_blackLevel_min, m_blackLevel_max, value);
    return true;
}







}


